 <template>
  <div class="d-flex flex-column flex-grow-1">
    <AxiomToolbar>
      <AxiomButton icon="arrow-left" @click="goBack">返回文档列表</AxiomButton>
    </AxiomToolbar>

    <AxiomCard class="mt-4 flex-grow-1">
      <template #header>
        <AxiomSteps :active="currentStep" align-center finish-status="success">
          <AxiomStep title="解析预览" description="检查文档解析是否正确" />
          <AxiomStep title="分块与索引策略" description="配置分块参数与索引流水线" />
          <AxiomStep title="最终确认" description="预览配置并准备执行" />
        </AxiomSteps>
      </template>

      <div class="flex-grow-1 h-100">
        <AxiomLoading v-if="loading" text="正在获取智能推荐并解析文档..." />

        <!-- Step 0: Parse & Edit -->
        <ParseAndEditStep
          v-if="!loading && currentStep === 0"
          class="flex-grow-1"
          :documents="parsedDocuments"
          :selected-document="selectedDocument"
          @update:selected-document="selectedDocument = $event"
          :editable-content="editableParsedContent"
          @update:editable-content="editableParsedContent = $event"
        />

        <!-- Step 1: Chunking Configuration & Preview -->
        <ChunkingStep
          v-if="!loading && currentStep === 1"
          class="flex-grow-1"
          :documents="parsedDocuments"
          :selected-document="selectedDocument"
          @update:selected-document="selectedDocument = $event"
          :config="indexingConfig"
          @update:config="indexingConfig = $event"
          :strategy-options="strategyOptions"
          :recommended-strategy="recommendedStrategy"
          :recommendation-reason="recommendationReason"
          :parser-type-options="parserTypeOptions"
          :embedding-profile-options="embeddingProfileOptions"
          :embedding-profiles-loading="embeddingProfilesLoading"
          :chunked-preview="chunkedPreview"
          :chunking-loading="chunkingLoading"
          @strategy-changed="handleStrategyChange"
          @refresh-preview="previewChunks"
        />
        
        <!-- Step 2: Final Confirmation -->
        <IndexingStep
          v-if="!loading && currentStep === 2"
          :documents="parsedDocuments"
          :config="indexingConfig"
        />
        
      </div>

      <template #footer>
        <div class="d-flex" :class="{'justify-content-between': currentStep > 0, 'justify-content-end': currentStep === 0}">
          <AxiomButton v-if="currentStep > 0" @click="currentStep--">返回上一步</AxiomButton>
          
          <AxiomGroup>
            <AxiomButton 
              v-if="currentStep === 0" 
              type="primary" 
              :disabled="!canProceed"
              :loading="loading"
              @click="goToChunkingStep"
            >
              下一步
            </AxiomButton>
            <AxiomButton 
              v-else-if="currentStep === 1" 
              type="primary" 
              :disabled="!canProceed"
              @click="currentStep++"
            >
              下一步
            </AxiomButton>
            <AxiomButton 
              v-else-if="currentStep === 2"
              type="primary" 
              :loading="isExecuting"
              @click="executeAndGoBack"
            >
              完成并执行索引
            </AxiomButton>
          </AxiomGroup>
        </div>
      </template>
    </AxiomCard>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, inject, watch } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { 
    AxiomSteps, AxiomStep, AxiomLoading, 
    AxiomButton, AxiomCard, AxiomGroup, AxiomToolbar, AxiomEmpty
} from 'axiom-view';
import { documentApi, knowledgeBaseApi, strategyApi } from '@/api';

import ParseAndEditStep from './components/ParseAndEditStep.vue';
import ChunkingStep from './components/ChunkingStep.vue';
import IndexingStep from './components/IndexingStep.vue';


const props = defineProps({
    knowledgeBaseId: { type: String, required: true }
});

// --- 核心依赖 ---
const route = useRoute();
const router = useRouter();
const { notification, logger } = inject('axiom-utils');

// --- 核心状态 ---
const loading = ref(true); // 控制整个页面的加载状态
const currentStep = ref(0); // 控制当前所在的步骤 (0: 解析, 1: 分块, 2: 确认)
const isExecuting = ref(false); // 控制“执行索引”按钮的加载状态

// --- 文档相关状态 ---
const documentIds = ref([]); // 从上一个页面传入的待索引文档ID列表
const parsedDocuments = ref([]); // 解析后的文档对象数组，包含内容和元数据
const selectedDocument = ref(null); // 左侧列表中当前选中的文档对象
const editableParsedContent = ref(''); // 在编辑器中显示的、可修改的文档内容

// --- 索引策略相关状态 ---
const strategyOptions = ref([]); // 可用的策略选项，用于下拉菜单
const recommendedStrategy = ref(''); // AI推荐的策略名称
const recommendationReason = ref(''); // AI推荐的理由
const indexingConfig = ref({ // 当前完整有效的索引配置
  document_ids: [],
  pipelines: []
});
const chunkingLoading = ref(false); // 分块预览的加载状态
// chunkedPreview 现在将存储一个 pipeline_results 数组
// 其结构为: [{ collection_name_suffix: string, split_nodes: { text: string }[] }]
const chunkedPreview = ref([]); // 分块预览的结果数组

// --- (遗留)内嵌模型相关状态 ---
const embeddingProfilesLoading = ref(false); // 加载嵌入模型的loading状态
const embeddingProfileOptions = ref([]); // 可用的嵌入模型选项

// --- 静态配置 ---
const parserTypeOptions = [ // 分块模式的选项
    { label: '普通分块', value: 'sentence_splitter' },
    { label: 'Token分块', value: 'token_splitter' },
    { label: '语义分块', value: 'semantic_splitter' },
    { label: 'Markdown分块', value: 'markdown_node' }
];

/**
 * 计算当前步骤是否可以进入下一步
 */
const canProceed = computed(() => {
  if (currentStep.value === 0) {
    // 步骤0：必须有选中的文档和可编辑的内容
    return selectedDocument.value && editableParsedContent.value;
  }
  if (currentStep.value === 1) {
    // 步骤1：必须有有效的索引配置和至少一个流水线
    return indexingConfig.value && indexingConfig.value.pipelines && indexingConfig.value.pipelines.length > 0;
  }
  return true;
});


/**
 * 组件挂载时的初始化逻辑
 */
onMounted(async () => {
    // 从路由状态中获取文档ID
    documentIds.value = window.history.state.documentIds || [];
    if (documentIds.value.length === 0) {
        notification.error({ title: '错误', message: '没有需要处理的文档ID' });
        goBack();
        return;
    }
    
    loading.value = true;
    try {
      // 仅获取并解析文档
      await fetchAndParseDocuments();
    } catch(error) {
       notification.error({ title: '初始化失败', message: `加载页面数据时出错: ${error.message}` });
       logger.error('Indexing page onMounted error:', error);
    } finally {
      loading.value = false;
    }
});

/**
 * 监听当前选中的文档，并更新编辑器内容
 */
watch(selectedDocument, (newDoc, oldDoc) => {
    if (newDoc && newDoc.parsed_documents) {
        editableParsedContent.value = newDoc.parsed_documents.map(doc => doc.text).join('\\n\\n---\\n\\n');
    } else {
        editableParsedContent.value = '';
    }
    // 当文档切换时，清空旧的预览
    chunkedPreview.value = [];

    // 如果我们正处于分块步骤，并且文档确实发生了改变，则自动刷新预览
    if (currentStep.value === 1 && newDoc?.document_id !== oldDoc?.document_id) {
        previewChunks();
    }
});

/**
 * 监听索引配置的变化，如果包含语义分块，则自动加载嵌入模型
 */
watch(() => indexingConfig.value, (config) => {
    const hasSemantic = config.pipelines.some(p => p.parser_type === 'semantic_splitter');
    if (hasSemantic) {
        fetchEmbeddingProfiles();
    }
}, { deep: true });

async function goToChunkingStep() {
    loading.value = true;
    try {
        await Promise.all([
            fetchAvailableStrategies(),
            fetchStrategySuggestion(),
        ]);
        currentStep.value = 1;
        // 进入分块页面后，自动进行一次预览
        await previewChunks();
    } catch(error) {
       notification.error({ title: '加载策略失败', message: `加载分块策略时出错: ${error.message}` });
       logger.error('Failed to load chunking strategies:', error);
    } finally {
        loading.value = false;
    }
}


/**
 * 返回到知识库的文档列表页面
 */
function goBack() {
  router.push({ 
    name: 'KnowledgeBaseDocuments', 
    params: { kb_id: props.knowledgeBaseId } 
  });
}

/**
 * 获取所有可用的索引策略
 */
async function fetchAvailableStrategies() {
    try {
        const res = await strategyApi.getAvailableStrategies();
        // 核心数据在 res.data 中
        strategyOptions.value = res.data || [];
    } catch(error) {
        logger.error("获取可用策略列表失败:", error);
        notification.error({ title: '网络错误', message: '无法加载分块策略列表' });
        throw error;
    }
}

/**
 * 根据文档ID列表获取智能推荐策略
 */
async function fetchStrategySuggestion() {
    if (documentIds.value.length === 0) return;

    try {
        const res = await strategyApi.getStrategySuggestion(documentIds.value);
        const suggestion = res.data;

        console.log('智能推荐 API 响应:', suggestion);

        recommendedStrategy.value = suggestion.recommended_strategy;
        recommendationReason.value = suggestion.recommendation_reason;
        
        console.log('设置的推荐策略:', recommendedStrategy.value);
        console.log('设置的推荐理由:', recommendationReason.value);

        indexingConfig.value = {
            ...suggestion.config,
            strategy_name: suggestion.recommended_strategy
        };
    } catch(error) {
        logger.error("获取智能推荐策略失败:", error);
        notification.warning({ title: '提示', message: '无法获取智能推荐策略，将加载默认配置。' });
        recommendedStrategy.value = '';
        recommendationReason.value = '';
        const fallbackStrategy = strategyOptions.value.length > 0 ? strategyOptions.value[0].value : 'DENSE_QA';
        await handleStrategyChange(fallbackStrategy);
    }
}

/**
 * 当用户手动切换策略时，获取该策略的默认配置
 * @param {string} strategyName - 新选择的策略名称
 */
async function handleStrategyChange(strategyName) {
    if (!strategyName) return;

    if (strategyName !== recommendedStrategy.value) {
        recommendationReason.value = '';
    }

    loading.value = true;
    try {
        const res = await strategyApi.getStrategyDefaultConfig(strategyName);
        indexingConfig.value = {
            ...res.data,
            strategy_name: strategyName
        };
    } catch(error) {
        logger.error(`获取策略 '${strategyName}' 的默认配置失败:`, error);
        notification.error({ title: '加载失败', message: `无法加载策略 '${strategyName}' 的配置。` });
    } finally {
        loading.value = false;
    }
}

/**
 * 获取并解析所有待处理的文档
 */
async function fetchAndParseDocuments() {
    try {
        const docIds = documentIds.value;

        // 使用 listAllDocuments 获取所有文档的元数据
        const listRes = await documentApi.listAllDocuments({ knowledge_base_id: props.knowledgeBaseId });
        const allDocs = listRes.data || [];
        const targetDocs = allDocs.filter(doc => docIds.includes(doc.id));

        // 逐个解析目标文档以获取其内容
        const parsePromises = targetDocs.map(doc => 
            documentApi.parseDocument(doc.id).then(res => ({
                ...doc, // 保留原始文档信息
                parsed_documents: res.data.parsed_documents || [{text: res.data.text || ''}],
                original_file_name: doc.file_name,
                document_id: doc.id
            })).catch(e => {
                logger.error(`文档解析失败 ${doc.id}:`, e);
                return null;
            })
        );
        
        const parsedResults = await Promise.all(parsePromises);
        parsedDocuments.value = parsedResults.filter(Boolean);

        if (parsedDocuments.value.length > 0) {
            selectedDocument.value = parsedDocuments.value[0];
        } else {
            notification.error({ title: '解析失败', message: '未能获取任何有效的文档解析结果。' });
        }
    } catch (error) {
        notification.error({ title: '错误', message: `解析文档失败: ${error.message}` });
        logger.error('获取和解析文档时出错:', error);
        throw error;
    }
}

/**
 * 获取分块预览
 */
async function previewChunks() {
    if (!selectedDocument.value) {
        chunkedPreview.value = [];
        return;
    }

    chunkingLoading.value = true;
    try {
        const payload = {
            document_ids: [selectedDocument.value.document_id],
            pipelines: indexingConfig.value.pipelines
        };

        const res = await documentApi.batchSplitDocuments(payload);
        
        // API 返回一个包含单个文档结果的数组
        if (res.data && res.data.length > 0) {
            // 我们关心的是该文档下各个流水线的预览结果
            chunkedPreview.value = res.data[0].pipeline_results || [];
        } else {
             chunkedPreview.value = [];
        }
    } catch(error) {
        logger.error("分块预览失败:", error);
        notification.error({ title: '预览失败', message: `分块预览失败: ${error.message}` });
        chunkedPreview.value = [];
    } finally {
        chunkingLoading.value = false;
    }
}


/**
 * 最终执行索引任务
 */
async function executeAndGoBack() {
  isExecuting.value = true;
  try {
    const payload = {
      ...indexingConfig.value,
      document_ids: documentIds.value,
    };
    delete payload.strategy_name;

    await knowledgeBaseApi.runIndexing(props.knowledgeBaseId, payload);
    notification.success({ title: '成功', message: '索引任务已成功提交' });
    goBack();
  } catch (error) {
    logger.error("执行索引失败:", error);
    notification.error({ title: '失败', message: `执行索引失败: ${error.message}` });
  } finally {
    isExecuting.value = false;
  }
}

/**
 * 为语义分块器获取可用的嵌入模型
 */
async function fetchEmbeddingProfiles() {
    if (embeddingProfileOptions.value.length > 0) return;
    embeddingProfilesLoading.value = true;
    try {
        const res = await knowledgeBaseApi.getEmbeddingProfileGroups();
        // 核心数据在 res.data 中
        const embeddingProfileGroups = res.data || [];
        const allSplittingModels = embeddingProfileGroups.flatMap(group => group.splitting_models || []);

        embeddingProfileOptions.value = allSplittingModels.map(profile => ({
            label: profile.display_text,
            value: profile.profile_name,
        }));
        
        // 自动为使用了语义分块且未配置模型的流水线选择一个默认模型
        indexingConfig.value.pipelines.forEach(pipeline => {
            if (pipeline.parser_type === 'semantic_splitter') {
                 // 防御性编程：确保 semantic_splitter_config 存在
                if (!pipeline.semantic_splitter_config) {
                    pipeline.semantic_splitter_config = {};
                }
                
                if (!pipeline.semantic_splitter_config.embedding_profile_name && embeddingProfileOptions.value.length > 0) {
                     pipeline.semantic_splitter_config.embedding_profile_name = embeddingProfileOptions.value[0].value;
                }
            }
        });

    } catch (error) {
        notification.error({ title: '错误', message: '加载嵌入模型配置失败' });
        logger.error('获取嵌入模型失败:', error);
    } finally {
        embeddingProfilesLoading.value = false;
    }
}
</script>